using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using JoyfulHomeJourney.BackEnd.Infrastructure.Atrributes;
using JoyfulHomeJourney.BackEnd.Infrastructure.Dtos.Requests.Objects;
using JoyfulHomeJourney.BackEnd.Infrastructure.Dtos.Responses;
using JoyfulHomeJourney.BackEnd.Infrastructure.Dtos.Responses.Objects;
using JoyfulHomeJourney.BackEnd.Infrastructure.EFCore;
using JoyfulHomeJourney.BackEnd.Server.EFCore;
using JoyfulHomeJourney.BackEnd.Server.Instances.Extends.Requests;
using JoyfulHomeJourney.BackEnd.Server.Instances.Extends.Responses;
using JoyfulHomeJourney.BackEnd.Server.Interfaces;
using Microsoft.EntityFrameworkCore;
namespace JoyfulHomeJourney.BackEnd.Server.Instances
{
/// <summary>
/// 一个类包含了服务类所需的所有仓库表的实例，仅提供给该服务类使用，请将所有服务类所需的仓库表的实例都放在该类中。
/// 仓库表的实例指提供了操作数据库指定表的所有方法的对象
/// </summary>
	internal class ShiftsEF
	{
		public ShiftsEF(DbContext dbContext)
		{
			shiftsServerEF = new ShiftsServerEF(dbContext);
			accountServerEF = new SysAccountsServerEF(dbContext);
            employeesServerEF = new EmployeesServerEF(dbContext);
            offlineOrdersServerEF = new OfflineOrdersServerEF(dbContext);
        }
		public ShiftsServerEF shiftsServerEF { get; set; }
        public SysAccountsServerEF accountServerEF { get; set; }
        public EmployeesServerEF employeesServerEF { get; set; }
        public OfflineOrdersServerEF offlineOrdersServerEF { get; set; }
    }
	[InjectClass]
	public class ShiftsServer : IShiftsServer
	{
		private readonly ShiftsEF _shiftsEF;//包含所有所需仓库表实现的对象
		// 请不要修改该构造方法,也无需添加属性，而应该在上面的EF类中添加属性和构造函数赋值语句
		public ShiftsServer(DbContext dbContext)
		{
			_shiftsEF = new ShiftsEF(dbContext);
		}
		public async Task<ResponseApiDto> AddAsync(RequestShiftsDto dto)
		{
			return ResponseApiDto.Create(await _shiftsEF.shiftsServerEF.AddAsync(dto.ToCreateEntity()));
		}
		public async Task<ResponseApiDto> DeleteAsync(RequestShiftsDto dto)
		{
			return ResponseApiDto.Create(await _shiftsEF.shiftsServerEF.DeleteAsync(dto.ToDeleteEntity()));
		}
		public async Task<ResponseApiDto> UpdateAsync(RequestShiftsDto dto)
		{
			
			var stthing = await _shiftsEF.shiftsServerEF.Query(d => d.EEmployeeId == dto.shiftId).OrderByDescending(d => d.EStartTime).FirstOrDefaultAsync();
			
            var transactions = await _shiftsEF.offlineOrdersServerEF.Query(d => stthing.EStartTime <= d.OoUpdateAt&&dto.endTime>=d.OoUpdateAt && d.OoStatus == "已支付").CountAsync();
            var amount = await _shiftsEF.offlineOrdersServerEF.Query(d => stthing.EStartTime <= d.OoUpdateAt && dto.endTime >= d.OoUpdateAt&&d.OoStatus== "已支付").Select(d=>d.OoPayCount).ToListAsync();
			decimal amo=0;
			foreach (var item in amount)
            {
				amo += (decimal)item;
            }
			stthing.ENumberOfTransactions = transactions;
			stthing.ETotalAmount = amo;
            stthing.EEndTime = dto.endTime;
			stthing.ERemark=dto.remark;

			return ResponseApiDto.Create(await _shiftsEF.shiftsServerEF.UpdateAllProperNotNullAsync(stthing));
		}
		public async Task<ResponseApiDto> PaginationAsync(int page, int limit, string key)
		{
			int total = 0;
			key = key ?? "";
			if (key!="") { 
				key=_shiftsEF.employeesServerEF.Query(d=>d.EName.Contains(key)).Select(d=>d.EId).ToString();
            }
			List<ResponseShiftsDto> data = new List<ResponseShiftsDto>();
			List<Shifts> shiftss = await _shiftsEF.shiftsServerEF.Pagination1(d=>d.EEmployeeId.Contains(key), false, d => d.EStartTime, out total, page, limit).ToListAsync();
			foreach (var shifts in shiftss)
			{
				data.Add(new ResponseShiftsDto
				{
					shiftId=shifts.EShiftId,
					employeeId=shifts.EEmployeeId,
					employeeName=await _shiftsEF.employeesServerEF.Query(d=>d.EId==shifts.EEmployeeId).Select(d=>d.EName).FirstOrDefaultAsync(),
					startTime=shifts.EStartTime,
                    register=shifts.ECashRegisterId,

                    endTime =shifts.EEndTime,
					numberOfTransactions=shifts.ENumberOfTransactions,
                    totalAmount=shifts.ETotalAmount,

                    remark =shifts.ERemark,
				});
			}
			return ResponseApiDto.Success("数据已获取", new ResponsePaginationDto { total=total,data=data});
		}
	}
}
